
#ifndef SMENUC_H
#define SMENUC_H


#include <string>
#include <vector>
#include <boost/function.hpp>
#include <input/inputSingleton.h>
#include <drawables/drawable.hpp>
#include <SFML/Audio.hpp>

class selection
{
public:
	selection( std::string const& NAME, drawable_ptr selectedPTR, drawable_ptr unselectedPTR )
	{
		selected = selectedPTR;
		unselected = unselectedPTR;
		name = NAME;
	}
	~selection()
	{
	}
	void drawSelected()
	{
		if( selected != nullptr ) selected->draw();
	}
	void drawUnselected()
	{
		if( unselected != nullptr ) unselected->draw();
	}
	void update( float delta_time )
	{
		if( selected != nullptr ) selected->update(delta_time);
		if( unselected != nullptr ) unselected->update(delta_time);
	}
	void reset()
	{
		if( selected != nullptr ) selected->reset();
		if( unselected != nullptr ) unselected->reset();
	}
	//////////////////////////////

	std::string name;	
	
private:
	drawable_ptr selected;
	drawable_ptr unselected;
};

#define MOVEMENTTIME 0.27f

typedef boost::function<void( int , std::string const&  )> BFCallback;

class Menu
{
public:

	void resetFocus()
	{
		currentFocus = 0;
	}
	void addSelection(  std::string const& name, drawable_ptr selectedPTR, drawable_ptr unselectedPTR )
	{
		m_selections.push_back( new selection(name, selectedPTR, unselectedPTR ) );
	}

	void setIncrementAction( int action ) { incrementAction = action; }
	void setDecrementAction( int action ) { decrementAction = action; }
	void setSelectAction( int action ) { selectAction = action; }

	void draw()
	{
		for( unsigned int i = 0; i < m_selections.size(); ++i )
		{
			if( (int)i == currentFocus )
				m_selections[i]->drawSelected();
			else
				m_selections[i]->drawUnselected();
		}
	}

	void update( BFCallback & menuCallback, float deltaTime )
	{
		int cf = currentFocus;
		totalTime += deltaTime;
		if( totalTime > MOVEMENTTIME )
		{
			// update input
			if( incrementAction >= 0 )
			{
				if( g_user_input.getActionInput( incrementAction ).status == keyHeld )
				{
					++currentFocus;
					totalTime = 0;
					if( currentFocus < (int)m_selections.size() )
						click.Play();
					else
						--currentFocus;
				}
			}
			if( decrementAction >= 0 )
			{
				if( g_user_input.getActionInput( decrementAction ).status == keyHeld )
				{
					--currentFocus;
					totalTime=0;
					if( currentFocus >= 0 )
						click.Play();
					else
						++currentFocus;
				}
			}
		}

		if( cf == currentFocus )
			m_selections[currentFocus]->update(deltaTime );
		else
			m_selections[currentFocus]->reset();

		// if selected tell world the index and name
		if( selectAction >= 0 )
		{
			if( g_user_input.getActionInput( selectAction ).status == keyPressed )
				menuCallback( currentFocus, m_selections[currentFocus]->name );
		}
	}

	void clear()
	{
		for( auto itr = m_selections.cbegin(); itr != m_selections.cend(); ++itr )
		{
			delete *(itr);
		}
		m_selections.clear();
	}

	const std::string& getFocusName() { return m_selections[currentFocus]->name;} 

//////////////////////////////////////////////////////////////////////////

private:
	std::vector<selection*> m_selections;

	int incrementAction;
	int decrementAction;
	int selectAction;

	sf::Music music;
	sf::Sound click;

	int currentFocus;

	float totalTime;

//----------------------------------------------------------------------------

public:
	Menu() : incrementAction(-1), decrementAction(-1), selectAction(-1), currentFocus(0), totalTime(0)
	{
		if( !music.OpenFromFile("./resources/audio/le.ogg"))
			assert( false && "music fail to load" );
		music.Play();

		if( g_cache.load_buffer("./resources/audio/pop.wav") )
			click.SetBuffer(*g_cache.get_buffer("./resources/audio/pop.wav") );
	}
	~Menu() 
	{
		music.Stop();
		clear();
	}

};


#endif
